package com.chongqing.shiro.util;

import java.util.Collection;
import java.util.Map;

/**
 * @Description: 基础类型数据、字符串、对象、容器非空或者“”验证等验证
 * -------------------
 * @Author: YangXingfu
 * @Date: 2018/12/18 15:58
 */

public class VerificationUtil {

    /**
     * 简体中文的正则表达式
     */
    private static final String REGEX_SIMPLE_CHINESE = "^[\u4E00-\u9FA5]+";

    /**
     * 字母数字的正则表达式
     */
    private static final String REGEX_ALPHANUMERIC = "[a-zA-Z0-9]+";

    /**
     * 整数或浮点数的正则表达式
     */
    private static final String REGEX_NUMERIC = "(\\+|-){0, 1}(\\d+)([.]?)(\\d*)";

    /**
     * 邮箱的正则表达式
     */
    private static final String  REGEX_EMAIL = ".+@.+\\.[a-z]+";

    /**
     * 身份证号码的正则表达式
     */
    private static final String REGEX_ID_CARD = "(\\d{14}|\\d{17})([xX])";

    /**
     * 判断字符串与正则表达式是否匹配
     * @param string 字符串
     * @param regex 正则表达式
     * @return true/false
     */
    public static boolean isRegexMatch(String string,  String regex) {

        return string != null && string.matches(regex);
    }

    /**
     * 判断字符串是否只包含数字和字母
     * @param string 字符串
     * @return true/false
     */
    public static Boolean isAlphanumeric(String string) {

        return isRegexMatch(string, REGEX_ALPHANUMERIC);
    }

    /**
     * 判断字符串是否是空白符
     *   Validators.isBlank(null)                = true
     *   Validators.isBlank(&quot;&quot;)        = true
     *   Validators.isBlank(&quot; &quot;)       = true
     *   Validators.isBlank("")                  = true
     *   Validators.isBlank(&quot;aa&quot;)      = false
     *   Validators.isBlank(&quot;  aa  &quot;)  = false
     * @param string
     * @return true/false
     */
    public static boolean isBlank(String string) {

        if (string == null || string.length() == 0 || string.trim().equals("")) {
            return true;
        }
        for (int i = 0; i < string.length(); i++) {
            if (Character.isWhitespace(string.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }

    public static <T> boolean isEmpty(T o) {
        if (o == null) {
            return true;
        }

        return false;
    }

    /**
     * 判断字符串是否为空
     * null 或者 "" 都为false
     * @param string 字符串
     * @return true/false
     */
    public static boolean isEmpty(String string) {

        if (string == null || string.trim().equals("")) {
            return true;
        }
        return false;
    }

    /**
     * 判断集合是否为空
     * @param collection 集合对象
     * @param <T>   泛型集合
     * @return 集合为null或者长度为0范围true，否则返回false
     */
    public static <T> boolean isEmpty(Collection<T> collection) {

        return collection == null || collection.isEmpty();
    }

    /**
     *
     * @param map 集合对象
     * @param <K> 集合key
     * @param <V> 集合value
     * @return 集合为null或者长度为0范围true，否则返回false
     */
    public static <K, V> boolean isEmpty(Map<K, V> map) {

        return map == null || map.isEmpty();
    }

    /**
     * 判断字符串是否是数字字符串
     * @param string 字符串
     * @return 如果字符串全为字符串类型的数字返回true， 否则返回false;
     */
    public static boolean isNumber(String string) {

        if (isEmpty(string)) {
            return false;
        }

        for (int i = 0; i < string.length(); i++) {
            if (string.charAt(i) > '9' || string.charAt(i) < '0') {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否是范围类的数字字符串
     * @param string 字符串
     * @param min 范围的最小值
     * @param max 范围的最大值
     * @param <T> 泛型参数
     * @return 字符串是范围数字字符串返回true，否则返回false
     */
    public static <T> boolean isNumber(String string, T min, T max) {

        if (!isNumber(string)) {
            return false;
        }

        if (min instanceof Integer) {
            int number = Integer.parseInt(string);
            return number >= (Integer) min && number <= (Integer) max;
        } else  if (min instanceof Long) {
            long number = Long.parseLong(string);
            return number >= (Long) min && number <= (Long) max;
        } else if (min instanceof Float) {
            float number = Float.parseFloat(string);
            return number >= (Float) min && number <= (Float) max;
        } else if (min instanceof Double) {
            double number = Double.parseDouble(string);
            return number >= (Double) min && number <=(Double) max;
        } else {
            return false;
        }
    }

    /**
     * 判断字符串是否为整数或者浮点数
     * @param string 字符串
     * @return 字符串为整数字符串或者浮点数字符串返回true, 否则返回false
     */
    public static boolean isNumeric(String string) {

        return isRegexMatch(string, REGEX_NUMERIC);
    }

    public static boolean isNumeric(String string, int decimalLength) {
        if (isEmpty(string) || decimalLength < 0) {
            return false;
        }

        String regex = "(\\+|-){0,1}(\\d+)([.]?)(\\d(0," + decimalLength + "})";
        return isRegexMatch(string, regex);
    }

    /**
     * 判断邮箱是否合法
     * @param string 字符串
     * @return 字符串为6位长度的数字字符串返回true, 否则返回false
     */
    public static boolean isPostCode(String string) {

        if (isEmpty(string)) {
            return false;
        }

        if (string.length() != 6 || !isNumber(string)) {
            return false;
        }

        return true;
    }

    /**
     * 判断字符串长度是否在限定范围内
     * @param string 字符串
     * @param minLength 最小长度
     * @param maxLength 最大长度
     * @return 字符串在限定范围内返回true，否则返回false
     */
    public static boolean isString(String string, int minLength, int maxLength) {

        if (isEmpty(string)) {
            return false;
        }

        if (minLength < 0 || maxLength < 0) {
            return false;
        }

        return string.length() >= minLength && string.length() <= maxLength;
    }

    /**
     * 判断字符串是否与日期格式相同
     * ValidatorUtil.isDate("2018-12-2") true
     * @param string 字符串
     * @return 字符串是日期格式返回true，否则返回false
     */
    public static boolean isDate(String string) {

        if (isEmpty(string) || string.length() > 10) {
            return false;
        }

        String[] parts = string.split("-");

        if (parts.length != 3) {
            return false;
        }

        if (!isNumber(parts[0], 1970, 9999) || !isNumber(parts[1], 1, 12)
                || !isNumber(parts[2], 1, 31)) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否是合法的时间字符串
     * ValidatorUtil.isTime("14:22:35") true
     * @param string 字符串
     * @return 合法的时间字符串返回true，否则返回false
     */
    public static boolean isTime(String string) {
        if (isEmpty(string) || string.length() > 8) {
            return false;
        }

        String[] parts = string.split(":");
        if (parts.length != 2 && parts.length != 3) {
            return false;
        }

        for (int i = 0; i < parts.length; i++) {
            if (parts[i].length() != 2 && parts[i].length() != 1) {
                return false;
            }
        }
        if (parts.length == 2) {
            return isNumber(parts[0], 0, 23) && isNumber(parts[1], 0, 59);
        } else if (parts.length == 3) {
            return isNumber(parts[0], 0, 23) && isNumber(parts[1], 0, 59) && isNumber(parts[2], 0, 59);
        } else {
            return false;
        }

    }

    /**
     * 判断是否是合法的日期时间字符砖
     * @param string 字符串
     * @return 合法的日期和时间字符串返回true， 否则返回false
     */
    public static boolean isDateTime(String string) {

        if (isEmpty(string) || string.length() > 19) {
            return false;
        }

        String parts[] = string.split(" ");
        if (parts.length != 2) {
            return false;
        }

        return isDate(parts[0]) && isTime(parts[1]);

    }

    /**
     * 判断是否是合法的身份证号码
     * 15位或者18位数字， 14位数字加x(X)字符或者17位数字加x(X)字符才是合法的身份证
     * @param string 字符串
     * @return 合法的身份证返回true, 否则返回false
     */
    public static boolean isIdCardnumber(String string) {


        return isRegexMatch(string, REGEX_ID_CARD);
    }

    /**
     * 判断是否是简体中文
     * @param string 字符串
     * @return 如果是简体中文返回true, 否则返回false
     */
    public static boolean isSimpleChinese(String string) {

        return isRegexMatch(string, REGEX_SIMPLE_CHINESE);
    }

    /**
     * 判断是否是合法的邮箱
     * @param string
     * @return true/false
     */
    public static boolean isEmail(String string) {

        return isRegexMatch(string, REGEX_EMAIL);
    }

    public static void main(String[] args) {
        System.out.println(isDateTime(("1995-12-31 23:59:59")));
    }
}